// ============================================
// TypeScript 类示例
// ============================================

export {}

// 1. 基本类定义
class Animal {
    name: string;
    
    constructor(name: string) {
        this.name = name;
    }
    
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

let animal = new Animal("Generic Animal");
animal.move(10);

// 2. 继承
class Dog extends Animal {
    breed: string;
    
    constructor(name: string, breed: string) {
        super(name); // 调用父类构造函数
        this.breed = breed;
    }
    
    move(distanceInMeters = 5) {
        console.log("Running...");
        super.move(distanceInMeters);
    }
    
    bark() {
        console.log("Woof! Woof!");
    }
}

let dog = new Dog("Buddy", "Golden Retriever");
dog.bark();
dog.move(10);

// 3. 访问修饰符
class Person {
    public name: string;        // 公共的，默认
    private age: number;        // 私有的
    protected email: string;    // 受保护的
    readonly id: number;        // 只读的
    
    constructor(name: string, age: number, email: string, id: number) {
        this.name = name;
        this.age = age;
        this.email = email;
        this.id = id;
    }
    
    public getAge(): number {
        return this.age;
    }
    
    protected getEmail(): string {
        return this.email;
    }
}

class Employee extends Person {
    private department: string;
    
    constructor(name: string, age: number, email: string, id: number, department: string) {
        super(name, age, email, id);
        this.department = department;
    }
    
    public getEmployeeDetails(): string {
        // 可以访问protected成员
        return `${this.name} works in ${this.department}, email: ${this.getEmail()}`;
    }
}

let employee = new Employee("John", 30, "john@example.com", 1, "IT");
console.log(employee.name); // 可以访问public成员
console.log(employee.getAge()); // 可以访问public方法
// console.log(employee.age); // 错误：age是private的
// console.log(employee.email); // 错误：email是protected的

// 4. 参数属性
// 简化构造函数参数声明
class Student {
    constructor(
        public name: string,
        private age: number,
        protected grade: string
    ) {
        // 不需要手动赋值，TypeScript会自动创建和赋值
    }
    
    getInfo(): string {
        return `${this.name} is ${this.age} years old, grade: ${this.grade}`;
    }
}

let student = new Student("Alice", 16, "10th");
console.log(student.getInfo());

// 5. 存取器 (getter/setter)
class Rectangle {
    private _width: number = 0;
    private _height: number = 0;
    
    get width(): number {
        return this._width;
    }
    
    set width(value: number) {
        if (value < 0) {
            throw new Error("Width cannot be negative");
        }
        this._width = value;
    }
    
    get height(): number {
        return this._height;
    }
    
    set height(value: number) {
        if (value < 0) {
            throw new Error("Height cannot be negative");
        }
        this._height = value;
    }
    
    get area(): number {
        return this._width * this._height;
    }
}

let rect = new Rectangle();
rect.width = 10;
rect.height = 5;
console.log(`Area: ${rect.area}`);

// 6. 静态属性和方法
class MathUtils {
    static PI: number = 3.14159;
    
    static calculateCircleArea(radius: number): number {
        return this.PI * radius * radius;
    }
    
    static calculateCircleCircumference(radius: number): number {
        return 2 * this.PI * radius;
    }
}

console.log(`Circle area: ${MathUtils.calculateCircleArea(5)}`);
console.log(`PI value: ${MathUtils.PI}`);

// 7. 抽象类
abstract class Shape {
    abstract calculateArea(): number;
    
    // 抽象类中也可以包含具体实现
    displayArea(): void {
        console.log(`Area is: ${this.calculateArea()}`);
    }
}

class Circle extends Shape {
    constructor(private radius: number) {
        super();
    }
    
    calculateArea(): number {
        return Math.PI * this.radius * this.radius;
    }
}

class Square extends Shape {
    constructor(private sideLength: number) {
        super();
    }
    
    calculateArea(): number {
        return this.sideLength * this.sideLength;
    }
}

let circle = new Circle(5);
let square = new Square(4);

circle.displayArea();
square.displayArea();

// 8. 类实现接口
interface Flyable {
    fly(): void;
}

interface Swimmable {
    swim(): void;
}

// 类可以实现多个接口
class Duck implements Flyable, Swimmable {
    fly(): void {
        console.log("Duck is flying");
    }
    
    swim(): void {
        console.log("Duck is swimming");
    }
}

let duck = new Duck();
duck.fly();
duck.swim();

// 9. 类作为接口使用
class Point {
    x: number;
    y: number;
    
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

// 类可以作为接口使用
interface Point3d extends Point {
    z: number;
}

let point3d: Point3d = { x: 1, y: 2, z: 3 };

console.log("=== 类示例完成 ===");